package ceshiren;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.qameta.allure.Allure;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

public class BasePage {
    public static Logger logger= LoggerFactory.getLogger(BasePage.class);
    public static WebDriver driver;
    ObjectMapper mapper=new ObjectMapper(new YAMLFactory());
    String browsname=System.getenv("browser");

    public BasePage(WebDriver basedriver) {
        driver=basedriver;
    }
    public BasePage(String url) {
        if("chrome".equals(browsname)){
            ChromeOptions options = new ChromeOptions();
            options.addArguments("--remote-allow-origins=*");
            options.addArguments("--headless");
            try {
                driver=new RemoteWebDriver(new URL("https://selenium-node.hogwarts.ceshiren.com/wd/hub"),options);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }  else if("firefox".equals(browsname)){
            driver=new FirefoxDriver();
         }else if("safari".equals(browsname)){
            driver=new SafariDriver();
        }
        waitforHide(3);
        //cookie登录
        cookieFileisDelete();
        cookieLogin(url);
    }

    private void cookieLogin(String url) {
        driver.get(url);
        //如果当前项目下cookie文件不存在----扫码登录
        File file = Paths.get("cookies.yaml").toFile();
        if(!file.exists()){
            saveCookie();
        }else {
            //cookie文件读取
            loadCookies();
        }
    }
    private void cookieFileisDelete() {
        File file = Paths.get("cookies.yaml").toFile();
        if(file.exists()){
            //如果文件存在，判断cookie失效时间
           //读取yaml文件
            //从yaml文件读取信息
            TypeReference<List<HashMap<String ,Object>>> objectTypeReference = new TypeReference<>(){};
            List<HashMap<String, Object>> cookies = null;
            try {
                cookies = mapper.readValue(new File("cookies.yaml"), objectTypeReference);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //读取出来的cookie对象获取 expiry 不为空的list集合
            List<Long> expiryList = new ArrayList<>();
            cookies.forEach(
                   cookie->{
                       if(cookie.get("expiry")!=null){
                           String expiry = cookie.get("expiry").toString();
                           long l = Long.parseLong(expiry);
                           expiryList.add(l);
                       }
                   }
            );
            //Long getCookieTime = expiryList.get(0) - 一年的毫秒级的数值:31536000000
            Long getCookieTime = expiryList.get(0) - 31536000000L;
            long now = System.currentTimeMillis();//当前的毫秒级别
            if( (now - getCookieTime)/1000  > 7200){
                //cookie文件删除操作
                if(file.delete()){
                    logger.info("文件删除成功");
                }else{
                    logger.info("文件删除失败");
                }
            }
        }
    }

    public void quitdriver(){
        driver.quit();
    }
    //封装显式等待
    public WebDriverWait waitforShow(int second){
        logger.info("显示等待"+second+"s=>++++++");
        return new WebDriverWait(driver, Duration.ofSeconds(second));
    }
    //封装隐式等待
    public void waitforHide(int second){
        logger.info("隐式等待"+second+"s=>++++++");
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(second));
    }
    //封装流等待
    public  FluentWait<WebDriver> waitforflue(){
        logger.info("流等待=>++++++");
        FluentWait<WebDriver> fluentwait = new FluentWait<>(driver)
                .withTimeout(Duration.ofSeconds(30))
                .pollingEvery(Duration.ofSeconds(5))
                .ignoring(NoSuchElementException.class);
        return fluentwait;
    }
    //封装log
    public void log(String info){
        logger.info("打印info信息=>"+info);
    }
    //封装find方法
    public WebElement find(By by){
        logger.info("查找控件=>"+by);
        return driver.findElement(by);
    }
    //封装find方法
    public List<WebElement> finds(By by){
        logger.info("查找控件=>"+by);
        return driver.findElements(by);
    }
    //截图
    public void savescreen()  {
        try {
            //生成时间戳
            long nowtime=System.currentTimeMillis();
            String picname="./files/"+nowtime+".png";
            //生成截图
            File currentpic=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(currentpic,new File(picname));
            //保存截图
            Allure.addAttachment("picture","image/png",new FileInputStream(picname),".png");
            //Allure.addAttachment("picture","image/png",Files.newInputStream(Paths.get(picname)),".png");
        } catch (IOException e) {
            logger.warn("截图错误"+e);
        }
    }
    //获取page source
    public void getPageSource(){
        try {
            String pageSource = driver.getPageSource();
            FileWriter fileWriter = null;
            fileWriter = new FileWriter("./files/page_source.text");
            fileWriter.write(pageSource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void saveCookie()  {
        //手动扫码登陆,确认登陆成功
        waitforShow(5).until(ExpectedConditions.urlContains("https://work.weixin.qq.com/wework_admin/frame"));
        //获取cookie
        Set<Cookie> cookies = driver.manage().getCookies();
        //把cookie写入文件(yaml,写文件)
        try {
            mapper.writeValue(new File("cookies.yaml"),cookies);
        } catch (IOException e) {
            e.printStackTrace();
        }
//        mapper.writeValue(Paths.get("cookies.yaml").toFile(), cookies);
    }
    public void loadCookies()  {
        //从yaml文件读取信息
        TypeReference<List<HashMap<String ,Object>>> objectTypeReference = new TypeReference<>(){};
        List<HashMap<String, Object>> cookies = null;
        try {
            cookies = mapper.readValue(new File("cookies.yaml"), objectTypeReference);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //将读取的cookie使用add方法加载到浏览器
        cookies.stream().forEach(
                cookie->{
                    driver.manage().addCookie(
                            new Cookie(cookie.get("name").toString(),cookie.get("value").toString()));
                }
        );
        //刷新页面
        driver.navigate().refresh();
    }

}
